---
title: Guide Documents > Core Library > TypedBody
---
import { Callout, Tabs } from 'nextra/components'

## Outline
```typescript filename="@nestia/core" showLineNumbers
export function TypedBody(): ParameterDecorator;
```

Request body decorator **20,000x** faster, even **easy to use**.

`@TypedBody()` is a decorator function parsing `application/json` typed request body, and validates the request body value type through [`typia.validate<T>()`](https://typia.io/docs/validators/validate) function. If the request body is not following the promised type, 400 bad request error would be thrown.

It is almost same with original `@Body()` function of `NestJS`, however, 20,000x faster. 

Also, `@TypedBody()` is much more easier to use than `class-validator`, because it can use pure TypeScript type. If you can't understand the word "pure TypeScript type", then move to below [**#How to use**](#how-to-use) section and read the `IBbsArticle.IUpdate` interface type. You may understand what it means.

<Callout type="info">

If you want other `Content-Type`, use one of below:

  - `application/x-www-form-urlencoded`: [`@TypedQuery.Body()`](./TypedQuery#typedquerybody).
  - `multipart/form-data`: [`@TypedFormData.Body()`](./TypedFormData#TypedFormDatabody)

</Callout>

<Callout type="warning">

`@TypedBody()` is not essential for [Swagger Documents](./sdk/swagger) or [SDK Library](./sdk/sdk) building.

Therefore, it is not a matter to use `@TypedBody()` or `@Body()` of the original NestJS.

</Callout>




## How to use
<Tabs 
  items={[
    <code>IAttachmentFile.ts</code>,
    <code>IBbsArticle.ts</code>,
    <code>BbsArticlesController.ts</code>,
    'Compiled JavaScript File',
  ]}
  defaultIndex={2}>
  <Tabs.Tab>
```typescript copy filename="IBbsArticle.ts" showLineNumbers
import { tags } from "typia";

export interface IBbsArticle extends IBbsArticle.IStore {
  id: string & tags.Format<"uuid">;
  created_at: string & tags.Format<"date-time">;
}
export namespace IBbsArticle {
  export interface IStore {
    title: string & tags.MinLength<3> & tags.MaxLength<50>;
    body: string;
    files: IAttachmentFile[];
  }
}
```
  </Tabs.Tab>
  <Tabs.Tab>
```typescript copy filename="IAttachmentFile.ts" showLineNumbers
import { tags } from "typia";

export interface IAttachmentFile {
  name: null | (string & tags.MinLength<1> & tags.MaxLength<255>);
  extension: null | (string & tags.MinLength<1> & tags.MaxLength<8>);
  url: string & tags.Format<"url">;
}
```
  </Tabs.Tab>
  <Tabs.Tab>
```typescript copy filename="BbsArticlesController.ts" showLineNumbers {11}
import { TypedBody, TypedRoute } from "@nestia/core";
import { Controller } from "@nestjs/common";
import { tags } from "typia";

import { IBbsArticle } from "./IBbsArticle";

@Controller("bbs/articles")
export class BbsArticlesController {
  @TypedRoute.Post()
  public async store(
    @TypedBody() input: IBbsArticle.IStore,
  ): Promise<IBbsArticle> {
    return {
      ...input,
      id: "2b5e21d8-0e44-4482-bd3e-4540dee7f3d6",
      created_at: "2023-04-23T12:04:54.168Z",
    };
  }
}
```
  </Tabs.Tab>
  <Tabs.Tab>
```javascript filename="BbsArticlesController.js" showLineNumbers {309-470}
"use strict";
var __decorate =
  (this && this.__decorate) ||
  function (decorators, target, key, desc) {
    var c = arguments.length,
      r =
        c < 3
          ? target
          : desc === null
          ? (desc = Object.getOwnPropertyDescriptor(target, key))
          : desc,
      d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
      r = Reflect.decorate(decorators, target, key, desc);
    else
      for (var i = decorators.length - 1; i >= 0; i--)
        if ((d = decorators[i]))
          r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
  };
var __metadata =
  (this && this.__metadata) ||
  function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
      return Reflect.metadata(k, v);
  };
var __param =
  (this && this.__param) ||
  function (paramIndex, decorator) {
    return function (target, key) {
      decorator(target, key, paramIndex);
    };
  };
var __awaiter =
  (this && this.__awaiter) ||
  function (thisArg, _arguments, P, generator) {
    function adopt(value) {
      return value instanceof P
        ? value
        : new P(function (resolve) {
            resolve(value);
          });
    }
    return new (P || (P = Promise))(function (resolve, reject) {
      function fulfilled(value) {
        try {
          step(generator.next(value));
        } catch (e) {
          reject(e);
        }
      }
      function rejected(value) {
        try {
          step(generator["throw"](value));
        } catch (e) {
          reject(e);
        }
      }
      function step(result) {
        result.done
          ? resolve(result.value)
          : adopt(result.value).then(fulfilled, rejected);
      }
      step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
  };
Object.defineProperty(exports, "__esModule", { value: true });
exports.BbsArticlesController = void 0;
const core_1 = require("@nestia/core");
const common_1 = require("@nestjs/common");
let BbsArticlesController = class BbsArticlesController {
  store(input) {
    return __awaiter(this, void 0, void 0, function* () {
      return Object.assign(Object.assign({}, input), {
        id: "2b5e21d8-0e44-4482-bd3e-4540dee7f3d6",
        created_at: "2023-04-23T12:04:54.168Z",
      });
    });
  }
};
exports.BbsArticlesController = BbsArticlesController;
__decorate(
  [
    core_1.TypedRoute.Post({
      type: "assert",
      assert: (input) => {
        const assert = (input) => {
          const __is = (input) => {
            const $io0 = (input) =>
              "string" === typeof input.id &&
              /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i.test(
                input.id,
              ) &&
              "string" === typeof input.created_at &&
              !isNaN(new Date(input.created_at).getTime()) &&
              "string" === typeof input.title &&
              3 <= input.title.length &&
              input.title.length <= 50 &&
              "string" === typeof input.body &&
              Array.isArray(input.files) &&
              input.files.every(
                (elem) =>
                  "object" === typeof elem && null !== elem && $io1(elem),
              );
            const $io1 = (input) =>
              (null === input.name ||
                ("string" === typeof input.name &&
                  1 <= input.name.length &&
                  input.name.length <= 255)) &&
              (null === input.extension ||
                ("string" === typeof input.extension &&
                  1 <= input.extension.length &&
                  input.extension.length <= 8)) &&
              "string" === typeof input.url &&
              /^[a-zA-Z0-9]+:\/\/(?:www.)?[-a-zA-Z0-9@:%._+~#=]{1,256}.[a-zA-Z0-9()]{1,6}\b(?:[-a-zA-Z0-9()@:%_+.~#?&/=]*)$/.test(
                input.url,
              );
            return "object" === typeof input && null !== input && $io0(input);
          };
          if (false === __is(input))
            ((input, _path, _exceptionable = true) => {
              const $guard = core_1.TypedRoute.Post.guard;
              const $ao0 = (input, _path, _exceptionable = true) =>
                (("string" === typeof input.id &&
                  (/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i.test(
                    input.id,
                  ) ||
                    $guard(_exceptionable, {
                      path: _path + ".id",
                      expected: 'string & Format<"uuid">',
                      value: input.id,
                    }))) ||
                  $guard(_exceptionable, {
                    path: _path + ".id",
                    expected: '(string & Format<"uuid">)',
                    value: input.id,
                  })) &&
                (("string" === typeof input.created_at &&
                  (!isNaN(new Date(input.created_at).getTime()) ||
                    $guard(_exceptionable, {
                      path: _path + ".created_at",
                      expected: 'string & Format<"date-time">',
                      value: input.created_at,
                    }))) ||
                  $guard(_exceptionable, {
                    path: _path + ".created_at",
                    expected: '(string & Format<"date-time">)',
                    value: input.created_at,
                  })) &&
                (("string" === typeof input.title &&
                  (3 <= input.title.length ||
                    $guard(_exceptionable, {
                      path: _path + ".title",
                      expected: "string & MinLength<3>",
                      value: input.title,
                    })) &&
                  (input.title.length <= 50 ||
                    $guard(_exceptionable, {
                      path: _path + ".title",
                      expected: "string & MaxLength<50>",
                      value: input.title,
                    }))) ||
                  $guard(_exceptionable, {
                    path: _path + ".title",
                    expected: "(string & MinLength<3> & MaxLength<50>)",
                    value: input.title,
                  })) &&
                ("string" === typeof input.body ||
                  $guard(_exceptionable, {
                    path: _path + ".body",
                    expected: "string",
                    value: input.body,
                  })) &&
                (((Array.isArray(input.files) ||
                  $guard(_exceptionable, {
                    path: _path + ".files",
                    expected: "Array<IAttachmentFile>",
                    value: input.files,
                  })) &&
                  input.files.every(
                    (elem, _index1) =>
                      ((("object" === typeof elem && null !== elem) ||
                        $guard(_exceptionable, {
                          path: _path + ".files[" + _index1 + "]",
                          expected: "IAttachmentFile",
                          value: elem,
                        })) &&
                        $ao1(
                          elem,
                          _path + ".files[" + _index1 + "]",
                          true && _exceptionable,
                        )) ||
                      $guard(_exceptionable, {
                        path: _path + ".files[" + _index1 + "]",
                        expected: "IAttachmentFile",
                        value: elem,
                      }),
                  )) ||
                  $guard(_exceptionable, {
                    path: _path + ".files",
                    expected: "Array<IAttachmentFile>",
                    value: input.files,
                  }));
              const $ao1 = (input, _path, _exceptionable = true) =>
                (null === input.name ||
                  ("string" === typeof input.name &&
                    (1 <= input.name.length ||
                      $guard(_exceptionable, {
                        path: _path + ".name",
                        expected: "string & MinLength<1>",
                        value: input.name,
                      })) &&
                    (input.name.length <= 255 ||
                      $guard(_exceptionable, {
                        path: _path + ".name",
                        expected: "string & MaxLength<255>",
                        value: input.name,
                      }))) ||
                  $guard(_exceptionable, {
                    path: _path + ".name",
                    expected:
                      "((string & MinLength<1> & MaxLength<255>) | null)",
                    value: input.name,
                  })) &&
                (null === input.extension ||
                  ("string" === typeof input.extension &&
                    (1 <= input.extension.length ||
                      $guard(_exceptionable, {
                        path: _path + ".extension",
                        expected: "string & MinLength<1>",
                        value: input.extension,
                      })) &&
                    (input.extension.length <= 8 ||
                      $guard(_exceptionable, {
                        path: _path + ".extension",
                        expected: "string & MaxLength<8>",
                        value: input.extension,
                      }))) ||
                  $guard(_exceptionable, {
                    path: _path + ".extension",
                    expected: "((string & MinLength<1> & MaxLength<8>) | null)",
                    value: input.extension,
                  })) &&
                (("string" === typeof input.url &&
                  (/^[a-zA-Z0-9]+:\/\/(?:www.)?[-a-zA-Z0-9@:%._+~#=]{1,256}.[a-zA-Z0-9()]{1,6}\b(?:[-a-zA-Z0-9()@:%_+.~#?&/=]*)$/.test(
                    input.url,
                  ) ||
                    $guard(_exceptionable, {
                      path: _path + ".url",
                      expected: 'string & Format<"url">',
                      value: input.url,
                    }))) ||
                  $guard(_exceptionable, {
                    path: _path + ".url",
                    expected: '(string & Format<"url">)',
                    value: input.url,
                  }));
              return (
                ((("object" === typeof input && null !== input) ||
                  $guard(true, {
                    path: _path + "",
                    expected: "IBbsArticle",
                    value: input,
                  })) &&
                  $ao0(input, _path + "", true)) ||
                $guard(true, {
                  path: _path + "",
                  expected: "IBbsArticle",
                  value: input,
                })
              );
            })(input, "$input", true);
          return input;
        };
        const stringify = (input) => {
          const $io1 = (input) =>
            (null === input.name ||
              ("string" === typeof input.name &&
                1 <= input.name.length &&
                input.name.length <= 255)) &&
            (null === input.extension ||
              ("string" === typeof input.extension &&
                1 <= input.extension.length &&
                input.extension.length <= 8)) &&
            "string" === typeof input.url &&
            /^[a-zA-Z0-9]+:\/\/(?:www.)?[-a-zA-Z0-9@:%._+~#=]{1,256}.[a-zA-Z0-9()]{1,6}\b(?:[-a-zA-Z0-9()@:%_+.~#?&/=]*)$/.test(
              input.url,
            );
          const $string = core_1.TypedRoute.Post.string;
          const $so0 = (input) =>
            `{"id":${$string(input.id)},"created_at":${$string(
              input.created_at,
            )},"title":${$string(input.title)},"body":${$string(
              input.body,
            )},"files":${`[${input.files
              .map((elem) => $so1(elem))
              .join(",")}]`}}`;
          const $so1 = (input) =>
            `{"name":${
              null !== input.name ? $string(input.name) : "null"
            },"extension":${
              null !== input.extension ? $string(input.extension) : "null"
            },"url":${$string(input.url)}}`;
          return $so0(input);
        };
        return stringify(assert(input));
      },
    }),
    __param(
      0,
      (0, core_1.TypedBody)({
        type: "assert",
        assert: (input) => {
          const __is = (input) => {
            const $io0 = (input) =>
              "string" === typeof input.title &&
              3 <= input.title.length &&
              input.title.length <= 50 &&
              "string" === typeof input.body &&
              Array.isArray(input.files) &&
              input.files.every(
                (elem) =>
                  "object" === typeof elem && null !== elem && $io1(elem),
              );
            const $io1 = (input) =>
              (null === input.name ||
                ("string" === typeof input.name &&
                  1 <= input.name.length &&
                  input.name.length <= 255)) &&
              (null === input.extension ||
                ("string" === typeof input.extension &&
                  1 <= input.extension.length &&
                  input.extension.length <= 8)) &&
              "string" === typeof input.url &&
              /^[a-zA-Z0-9]+:\/\/(?:www.)?[-a-zA-Z0-9@:%._+~#=]{1,256}.[a-zA-Z0-9()]{1,6}\b(?:[-a-zA-Z0-9()@:%_+.~#?&/=]*)$/.test(
                input.url,
              );
            return "object" === typeof input && null !== input && $io0(input);
          };
          if (false === __is(input))
            ((input, _path, _exceptionable = true) => {
              const $guard = core_1.TypedBody.guard;
              const $ao0 = (input, _path, _exceptionable = true) =>
                (("string" === typeof input.title &&
                  (3 <= input.title.length ||
                    $guard(_exceptionable, {
                      path: _path + ".title",
                      expected: "string & MinLength<3>",
                      value: input.title,
                    })) &&
                  (input.title.length <= 50 ||
                    $guard(_exceptionable, {
                      path: _path + ".title",
                      expected: "string & MaxLength<50>",
                      value: input.title,
                    }))) ||
                  $guard(_exceptionable, {
                    path: _path + ".title",
                    expected: "(string & MinLength<3> & MaxLength<50>)",
                    value: input.title,
                  })) &&
                ("string" === typeof input.body ||
                  $guard(_exceptionable, {
                    path: _path + ".body",
                    expected: "string",
                    value: input.body,
                  })) &&
                (((Array.isArray(input.files) ||
                  $guard(_exceptionable, {
                    path: _path + ".files",
                    expected: "Array<IAttachmentFile>",
                    value: input.files,
                  })) &&
                  input.files.every(
                    (elem, _index1) =>
                      ((("object" === typeof elem && null !== elem) ||
                        $guard(_exceptionable, {
                          path: _path + ".files[" + _index1 + "]",
                          expected: "IAttachmentFile",
                          value: elem,
                        })) &&
                        $ao1(
                          elem,
                          _path + ".files[" + _index1 + "]",
                          true && _exceptionable,
                        )) ||
                      $guard(_exceptionable, {
                        path: _path + ".files[" + _index1 + "]",
                        expected: "IAttachmentFile",
                        value: elem,
                      }),
                  )) ||
                  $guard(_exceptionable, {
                    path: _path + ".files",
                    expected: "Array<IAttachmentFile>",
                    value: input.files,
                  }));
              const $ao1 = (input, _path, _exceptionable = true) =>
                (null === input.name ||
                  ("string" === typeof input.name &&
                    (1 <= input.name.length ||
                      $guard(_exceptionable, {
                        path: _path + ".name",
                        expected: "string & MinLength<1>",
                        value: input.name,
                      })) &&
                    (input.name.length <= 255 ||
                      $guard(_exceptionable, {
                        path: _path + ".name",
                        expected: "string & MaxLength<255>",
                        value: input.name,
                      }))) ||
                  $guard(_exceptionable, {
                    path: _path + ".name",
                    expected:
                      "((string & MinLength<1> & MaxLength<255>) | null)",
                    value: input.name,
                  })) &&
                (null === input.extension ||
                  ("string" === typeof input.extension &&
                    (1 <= input.extension.length ||
                      $guard(_exceptionable, {
                        path: _path + ".extension",
                        expected: "string & MinLength<1>",
                        value: input.extension,
                      })) &&
                    (input.extension.length <= 8 ||
                      $guard(_exceptionable, {
                        path: _path + ".extension",
                        expected: "string & MaxLength<8>",
                        value: input.extension,
                      }))) ||
                  $guard(_exceptionable, {
                    path: _path + ".extension",
                    expected: "((string & MinLength<1> & MaxLength<8>) | null)",
                    value: input.extension,
                  })) &&
                (("string" === typeof input.url &&
                  (/^[a-zA-Z0-9]+:\/\/(?:www.)?[-a-zA-Z0-9@:%._+~#=]{1,256}.[a-zA-Z0-9()]{1,6}\b(?:[-a-zA-Z0-9()@:%_+.~#?&/=]*)$/.test(
                    input.url,
                  ) ||
                    $guard(_exceptionable, {
                      path: _path + ".url",
                      expected: 'string & Format<"url">',
                      value: input.url,
                    }))) ||
                  $guard(_exceptionable, {
                    path: _path + ".url",
                    expected: '(string & Format<"url">)',
                    value: input.url,
                  }));
              return (
                ((("object" === typeof input && null !== input) ||
                  $guard(true, {
                    path: _path + "",
                    expected: "IBbsArticle.IStore",
                    value: input,
                  })) &&
                  $ao0(input, _path + "", true)) ||
                $guard(true, {
                  path: _path + "",
                  expected: "IBbsArticle.IStore",
                  value: input,
                })
              );
            })(input, "$input", true);
          return input;
        },
      }),
    ),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise),
  ],
  BbsArticlesController.prototype,
  "store",
  null,
);
exports.BbsArticlesController = BbsArticlesController = __decorate(
  [(0, common_1.Controller)("bbs/articles")],
  BbsArticlesController,
);
```
  </Tabs.Tab>
</Tabs>

Just call `@TypedBody()` function on the request body parameter, that's all.

`Nestia` will analyze your type (`IBbsArticle.IUpdate`), and writes optimal code for the target type, in the compilation level. If you click the "Complied JavaScript File" tab of above, you can see the optimal validation code. 

Such optimization is called AOT (Ahead of Time) compilation, and it is the secret of `@TypedBody`.




## Special Tags
You can enhance validation logic, of `@TypedBody()`, through special tags.

You know what? `@TypedBody()` utilizes [`typia.validate<T>()`](https://typia.io/docs/validators/validate) function for request body data validation, and the [`typia.validate<T>()`](https://typia.io/docs/validators/validate) function supports additional type checking logics through type and comment tags. For reference, "Type Tag" means a intersection type with atomic type and special tag type of `typia` like `number & tags.Type<"uint32">`, and "Comment Tag" means a comment starting from `@` symbol following `@${name} ${value}` format.

With those type and comment tags, you can add additional validation logics. If you want to add a custom validation logic, you also can do it. Read below Guide Documents of [typia](https://typia.io), and see the example code. You may understand how to utilize such type and comment tags, in a few minutes.

  - [**`typia` > Validators > Custom Tags**](https://typia.io/docs/validators/tags/)
    - [Outline](https://typia.io/docs/validators/tags/#outline)
    - [Type Tags](https://typia.io/docs/validators/tags/#type-tags)
    - [Comment Tags](https://typia.io/docs/validators/tags/#comment-tags)
    - [Customization](https://typia.io/docs/validators/tags/#customization)

<Tabs items={['TypeScript Source Code', 'Compiled JavaScript File']}>
  <Tabs.Tab>
```typescript copy filename="examples/src/is-special-tags.ts" showLineNumbers {3}
import typia, { tags } from "typia";

export const checkSpecialTag = typia.createIs<SpecialTag>();

interface SpecialTag {
  int32: number & tags.Type<"int32">;
  range?: number & tags.ExclusiveMinimum<19> & tags.Maximum<100>;
  minLength: string & tags.MinLength<3>;
  pattern: string & tags.Pattern<"^[a-z]+$">;
  date: null | (string & tags.Format<"date">);
  ip: string & (tags.Format<"ipv4"> | tags.Format<"ipv6">);
  uuids: Array<string & tags.Format<"uuid">> &
    tags.MinItems<3> &
    tags.MaxItems<100>;
}
```
  </Tabs.Tab>
  <Tabs.Tab>
```javascript filename="examples/bin/is-special-tags.js" showLineNumbers {10-45}
"use strict";
var __importDefault =
  (this && this.__importDefault) ||
  function (mod) {
    return mod && mod.__esModule ? mod : { default: mod };
  };
Object.defineProperty(exports, "__esModule", { value: true });
exports.checkSpecialTag = void 0;
const typia_1 = __importDefault(require("typia"));
const checkSpecialTag = (input) => {
  const $io0 = (input) =>
    "number" === typeof input.int32 &&
    Math.floor(input.int32) === input.int32 &&
    -2147483648 <= input.int32 &&
    input.int32 <= 2147483647 &&
    (undefined === input.range ||
      ("number" === typeof input.range &&
        19 < input.range &&
        input.range <= 100)) &&
    "string" === typeof input.minLength &&
    3 <= input.minLength.length &&
    "string" === typeof input.pattern &&
    /^[a-z]+$/.test(input.pattern) &&
    (null === input.date ||
      ("string" === typeof input.date &&
        /^(d{4})-(d{2})-(d{2})$/.test(input.date))) &&
    "string" === typeof input.ip &&
    (/^(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(
      input.ip,
    ) ||
      /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/.test(
        input.ip,
      )) &&
    Array.isArray(input.uuids) &&
    3 <= input.uuids.length &&
    input.uuids.length <= 100 &&
    input.uuids.every(
      (elem) =>
        "string" === typeof elem &&
        /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i.test(
          elem,
        ),
    );
  return "object" === typeof input && null !== input && $io0(input);
};
exports.checkSpecialTag = checkSpecialTag;
```
  </Tabs.Tab>
</Tabs>




## `EncryptedBody`
Encrypted request body decorator function.

`@EncryptedBody()` is a decorator function similar with `@TypedBody()`, but it encrypts the request body through AES-128/256-CBC algorithm like below. Therefore, it would be slower than `@TypedBody()`, but it guarantees the security of request body data.

  - AES-128/256
  - CBC mode
  - PKCS #5 Padding
  - Base64 Encoding

For reference, such encryption spec is not supported in the [Swagger-UI](../sdk/swagger). Instead, [SDK (Software Development Kit)](../sdk/sdk) generated by `@nestia/sdk` supports it. Thus, you have to build and distribute the SDK library to the client developers when using such encryption decorators.




## Configuration
```json filename="tsconfig.json" showLineNumbers {8}
{
  "compilerOptions": {
    "strict": true,
    "plugins": [
      { "transform": "typia/lib/transform" },
      {
        "transform": "@nestia/core/lib/transform",
        "validate": "validate",
        // "llm": {
        //   "model": "chatgpt",
        //   "strict": true,
        // },
      }
    ]
  }
}
```

Change type validation function to another one.

If you configure `validate` property of plugin defined in the `tsconfig.json` file, you can change the `@TypedBody()` to use another validation function instead of the default [`typia.validate<T>`](https://typia.io/docs/validators/validate) function. For example, if you want to use [`typia.validateEquals<T>()`](https://typia.io/docs/validators/validate/#validateequals-function) function instead, then set the `validate` property to `validateEquals`.

Below is the list of available validation functions.

  - [`is`](https://typia.io/docs/validators/is/) or [`equals`](https://typia.io/docs/validators/is/#equals-function): check validation only, and do not reveal the reason why 
  - [`assert`](https://typia.io/docs/validators/assert/) or [`assertEquals`](https://typia.io/docs/validators/assert/#assertequals-function): find the 1st type error with reason
  - [`validate`](https://typia.io/docs/validators/validate/) or [`validateEquals`](https://typia.io/docs/validators/validate/#validateequals-function): find every type errors with detailed reasons
  - [`assertPrune`](https://typia.io/docs/misc/#prune-functions) or [`validatePrune`](https://typia.io/docs/misc/#prune-functions): prune extra properties with type checking
  - [`assertClone`](https://typia.io/docs/misc/#clone-functions) or [`validateClone`](https://typia.io/docs/misc/#clone-functions): deep clone with type checking for faster pruning

Also, if you configure `llm` property of the plugin, `@nestia/core` considers that your backend application has been developed for LLM function calling, and validates the request/response body types following the target LLM model's restrictions. 

For example, if you configure `chatgpt` with `strict` option, dynamic properties and optional properties are not allowed in the request/response body types. If your some request/response body types are not following the target LLM model's restrictions, `@nestia/core` will throw a compilation error.

Here is the list of available LLM models. Read their definitions, and follow their restrictions.

  - Supported schemas
    - `"chatgpt"`: ([`IChatGptSchema`](https://github.com/samchon/openapi/blob/master/src/structures/IChatGptSchema.ts)), OpenAI ChatGPT
    - `"claude"`: ([`IClaudeSchema`](https://github.com/samchon/openapi/blob/master/src/structures/IClaudeSchema.ts)), Anthropic Claude
    - `"gemini"`: ([`IGeminiSchema`](https://github.com/samchon/openapi/blob/master/src/structures/IGeminiSchema.ts)), Google Gemini
    - `"llama"`: ([`ILlamaSchema`](https://github.com/samchon/openapi/blob/master/src/structures/ILlamaSchema.ts)), Meta Llama
  - Midldle layer schemas
    - `"3.0"`: ([`ILlmSchemaV3`](https://github.com/samchon/openapi/blob/master/src/structures/ILlmSchemaV3.ts)), middle layer based on OpenAPI v3.0 specification
    - `"3.1"`: ([`ILlmSchemaV3_1`](https://github.com/samchon/openapi/blob/master/src/structures/ILlmSchemaV3_1.ts)), middle layer based on OpenAPI v3.1 specification




## Benchmark
Super-fast and super-safe.

`Nestia` utilizes [typia](https://typia.io/docs/), and `NestJS` uses `class-validator`. One thing amazing is, `typia` is maximum 20,000x faster than `class-validator` of `NestJS`. Color of `class-transformer` is skyblue, and can you find the skyblue color in the below benchmark graph? It may hard to find because `class-validator` is extremely slow.

![Validate Function Benchmark](https://github.com/samchon/typia/raw/master/benchmark/results/AMD%20Ryzen%209%207940HS%20w%20Radeon%20780M%20Graphics/images/validate.svg)

> Measured on [AMD R9-7940HS, Rog Flow X13](https://github.com/samchon/typia/tree/master/benchmark/results/AMD%20Ryzen%209%207940HS%20w%20Radeon%20780M%20Graphics#validate)

Furthermore, while other libraries can't validate complicate union types, `typia` can validate every TypeScript types. However, in the `class-validator` case, it always be failed when any type of complicate comes. I can't understand why `NestJS` has adopted such slow and unstable library.

Moreover, only `typia` can utilize pure TypeScript type, without any extra schema definition. Beside, all of other libraries require extra and duplicated schema definition, different with pure TypeScript type. `Nestia` is using such wonderful, super-fast and super-fast `typia` library.

  - `TypeBox` requires [`TypeBox` schema](https://github.com/samchon/typia/blob/master/benchmark/src/structures/typebox/TypeboxObjectHierarchical.ts)
  - `ajv` requires [JSON schema definition](https://github.com/samchon/typia/blob/master/test/schemas/json/swagger/ObjectHierarchical.json)
  - `io-ts` requires [`io-ts` schema](https://github.com/samchon/typia/blob/master/benchmark/src/structures/io-ts/IoTsObjectHierarchical.ts)
  - `zod` requires [`zod` schema](https://github.com/samchon/typia/blob/master/benchmark/src/structures/zod/ZodObjectHierarchical.ts)
  - `class-validator` requires [DTO class with decorator function calls](https://github.com/samchon/typia/blob/master/benchmark/src/structures/class-validator/ClassValidatorObjectHierarchical.ts)

Components               | `typia` | `TypeBox` | `ajv` | `io-ts` | `zod` | `C.V.`
-------------------------|--------|-----------|-------|---------|-------|------------------
**Easy to use**          | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ 
[Object (simple)](https://github.com/samchon/typia/blob/master/test/src/structures/ObjectSimple.ts)          | ✔ | ✔ | ✔ | ✔ | ✔ | ✔
[Object (hierarchical)](https://github.com/samchon/typia/blob/master/test/src/structures/ObjectHierarchical.ts)    | ✔ | ✔ | ✔ | ✔ | ✔ | ✔
[Object (recursive)](https://github.com/samchon/typia/blob/master/test/src/structures/ObjectRecursive.ts)       | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔
[Object (union, implicit)](https://github.com/samchon/typia/blob/master/test/src/structures/ObjectUnionImplicit.ts) | ✅ | ❌ | ❌ | ❌ | ❌ | ❌
[Object (union, explicit)](https://github.com/samchon/typia/blob/master/test/src/structures/ObjectUnionExplicit.ts) | ✔ | ✔ | ✔ | ✔ | ✔ | ❌
[Object (additional tags)](https://github.com/samchon/typia/#comment-tags)        | ✔ | ✔ | ✔ | ✔ | ✔ | ✔
[Object (template literal types)](https://github.com/samchon/typia/blob/master/test/src/structures/TemplateUnion.ts) | ✔ | ✔ | ✔ | ❌ | ❌ | ❌
[Object (dynamic properties)](https://github.com/samchon/typia/blob/master/test/src/structures/DynamicTemplate.ts) | ✔ | ✔ | ✔ | ❌ | ❌ | ❌
[Array (rest tuple)](https://github.com/samchon/typia/blob/master/test/src/structures/TupleRestAtomic.ts) | ✅ | ❌ | ❌ | ❌ | ❌ | ❌
[Array (hierarchical)](https://github.com/samchon/typia/blob/master/test/src/structures/ArrayHierarchical.ts)     | ✔ | ✔ | ✔ | ✔ | ✔ | ✔
[Array (recursive)](https://github.com/samchon/typia/blob/master/test/src/structures/ArrayRecursive.ts)        | ✔ | ✔ | ✔ | ✔ | ✔ | ❌
[Array (recursive, union)](https://github.com/samchon/typia/blob/master/test/src/structures/ArrayRecursiveUnionExplicit.ts) | ✔ | ✔ | ❌ | ✔ | ✔ | ❌
[Array (R+U, implicit)](https://github.com/samchon/typia/blob/master/test/src/structures/ArrayRecursiveUnionImplicit.ts)    | ✅ | ❌ | ❌ | ❌ | ❌ | ❌
[**Ultimate Union Type**](https://github.com/samchon/typia/blob/master/src/schemas/IJsonSchema.ts)  | ✅ | ❌ | ❌ | ❌ | ❌ | ❌

> `C.V.` means `class-validator`